//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
//

#include "WSNWorldUtilityStats.h"
#include "Packet.h"

#define TIMER_VECTORS 100
Define_Module(WSNWorldUtilityStats);

void WSNWorldUtilityStats::initialize(int stage)
{
	BaseWorldUtility::initialize(stage);

	if(stage == 0) {
		EV<<"start initial worldUtlty"<<endl;
		recordVectors = par("recordVectors");
		bitrate = par("bitrate");
		vectorsInterval = par("vectorsInterval");
		bitsSent = 0;
		bitsReceived = 0;

		//register for global stats to collect
		Packet tmp(10);
		catPacket = subscribe(this, &tmp);

		sent.setName("Bits generated");
		rcvd.setName("Bits received");
		netUsage.setName("netUsage");
		netTraffic.setName("netTraffic");
	}else{

		if(recordVectors) {
			vectorsTimer = new cMessage("vectorsTimer",TIMER_VECTORS);
			scheduleAt(simTime()+vectorsInterval,vectorsTimer);
		}
	}
}


void WSNWorldUtilityStats::receiveBBItem(int category, const BBItem *details, int scopeModuleId)
{
	if(category == catPacket)
	{
		const Packet* p = static_cast<const Packet*>(details);
		double nbBitsSent = p->getNbBitsSent();
		double nbBitsRcvd = p->getNbBitsReceived();
		bitsSent += nbBitsSent;
		bitsReceived += nbBitsRcvd;
	}
	else {
		opp_error("BBItem of unexpected category: %s", details->getClassName());
	}

}

void WSNWorldUtilityStats::finish()
{
	recordScalar("GlobalTrafficGenerated", bitsSent, "bit");
	recordScalar("GlobalTrafficReceived", bitsReceived, "bit");
	recordScalar("Traffic", bitsSent / bitrate / simTime());
	double hosts = simulation.getSystemModule()->par("numHosts");
	if(!par("bcTraffic"))
		hosts = 2;
	recordScalar("Usage", bitsReceived / bitrate / simTime() / (hosts-1));
}

void WSNWorldUtilityStats::handleMessage(cMessage* msg){
	if(msg->getKind()){
		double hosts = simulation.getSystemModule()->par("numHosts");
		netUsage.record(bitsReceived / (bitrate* simTime().dbl()* hosts-1));
		netTraffic.record(bitsSent / (bitrate * simTime().dbl()));
		scheduleAt(simTime()+vectorsInterval,vectorsTimer);

	}

}



